%{
#include <iostream>
#include "elisa_lexer.h"

typedef elisa::Parser::token token;
typedef elisa::Parser::token_type token_type;

#define yyterminate() return token::END

#define YY_NO_UNISTD_H
%}

%option c++
%option batch
%option yywrap nounput 


enter				"\n"
space				[ \t\r]+

lbr					"("
rbr					")"
lsbr				"["
rsbr				"]"
dollar				"$"
twopoints			".."
realposinfinity		"+oo"|"+Inf"|"+INF"|"+inf"
realneginfinity		"-oo"|"-Inf"|"-INF"|"-inf"
pred				"pred"
succ				"succ"

num					[0-9]
add					"+"
sub					"-"
sign				({add}|{sub})
integer1			{num}+
exp					(E|e)

mk					"."
float1				{num}*{mk}{num}+
float2				{num}*{mk}{num}+{exp}{num}+
float3				{num}*{mk}{num}+{exp}{sign}{num}+


div					"/"
pow					"**"|"^"
psup				">="
pinf				"<="

comment				"%".*

pragmamaxtime		"Time"|"TIME"|"time"
pragmaconstants		"Constants"|"CONSTANTS"|"constants"|"Constant"|"CONSTANT"|"constant"
pragmadomains		"Domains"|"DOMAINS"|"domains"|"Variables"|"VARIABLES"|"variables"|"Variable"|"variable"|"VARIABLE"
pragmaconstraints	"Constraints"|"CONSTRAINTS"|"constraints"|"Constraint"|"CONSTRAINT"|"constraint"
pragmabisection		"Bisection"|"BISECTION"|"bisection"|"Branch"|"branch"|"BRANCH"
pragmaoutput		"Output"|"OUTPUT"|"output"

bisectionchoice		"Choice"|"CHOICE"|"choice"
bisectionparts		"Parts"|"PARTS"|"parts"
nobisection			"None"|"NONE"|"none"

bisectionchoicerr	"rr"|"RR"|"round_robin"|"ROUND_ROBIN"|"Round_Robin"
bisectionchoicelf	"lf"|"LF"|"largest_first"|"LARGEST_FIRST"|"Largest_First"
bisectionchoicemn	"mn"|"MN"|"max_narrow"|"MAX_NARROW"|"Max_Narrow"

bisectionnumber		"Number"|"number"|"NUMBER"

bisectionsubpaving	"paving"|"Paving"|"PAVING"
bisectionpoints		"points"|"Points"|"POINTS"

precision			"Precision"|"PRECISION"|"precision"|"Prec"|"PREC"|"prec"

mode				"Mode"|"MODE"|"mode"

outputhullmode		"Hull"|"HULL"|"hull"
outputunionmode		"Union"|"UNION"|"union"
outputdigits		"Digits"|"DIGITS"|"digits"
outputstyle			"Style"|"STYLE"|"style"
outputboundstyle	"Bound"|"BOUND"|"bound"|"Bounds"|"BOUNDS"|"bounds"
outputmidpointstyle	"Midpoint"|"MIDPOINT"|"midpoint"|"Mid"|"MID"|"mid"
outputsolution		"Solutions"|"SOLUTIONS"|"solutions"|"Sol"|"SOL"|"sol"|"Solution"|"SOLUTION"|"solution"
outputallsolution	"All"|"ALL"|"all"

pragmaconsistency	"Consistency"|"CONSISTENCY"|"consistency"
localconsistency	"Local"|"LOCAL"|"local"
strongconsistency	"Strong"|"STRONG"|"strong"

consistencybc3		"BC3"|"bc3"|"box"|"BOX"|"Box"
consistencybc3newton "BC3_NEWTON"|"bc3_newton"|"BOX_NEWTON"|"box_newton"|"Box_Newton"|"NUMERICA"|"Numerica"|"numerica"
consistencybc4		"BC4"|"bc4"|"hull_box"|"HULL_BOX"|"Hull_Box"
consistencybc5		"BC5"|"bc5"|"hull_box_newton"|"HULL_BOX_NEWTON"|"Hull_Box_Newton"|"Best"|"BEST"|"best"
consistencyhc3		"HC3"|"hc3"|"hull_decomp"|"HULL_DECOMP"|"Hull_Decomp"
consistencyhc4		"HC4"|"hc4"|"hull"|"HULL"|"Hull"
consistencyhc4i		"HC4I"|"hc4i"|"hc4I"
consistencyhc4newton "HC4_NEWTON"|"HC4_Newton"|"hc4_Newton"|"hc4_newton"|"hull_newton"|"HULL_NEWTON"|"Hull_Newton"

consistency3b		"3B"|"3b"
consistencyweak3b	"weak3B"|"WEAK3B"|"Weak3B"|"weak3b"|"WEAK3b"|"Weak3b"
precision3b			"width"|"WIDTH"|"Width"
precision2b			"phi"|"Phi"|"PHI"

improvement2b		"improve"|"IMPROVE"|"Improve"

minimum				"min"
maximum				"max"
integertype			"int"
realtype			"real"

ident				[a-zA-Z@][a-zA-Z0-9_]*

%{
#define YY_USER_ACTION  yylloc->columns(yyleng);
%}

%% /// regular expressions part

%{
	// reset location
	yylloc->step();
%}

{pragmamaxtime}			{return(token::PRAGMAMAXTIME);}
{pragmaconstants}		{return(token::PRAGMACONSTANTS);}
{pragmadomains}			{return(token::PRAGMADOMAINS);}
{pragmaconstraints}		{return(token::PRAGMACONSTRAINTS);}
{pragmabisection}		{return(token::PRAGMABISECTION);}
{pragmaoutput}			{return(token::PRAGMAOUTPUT);}

{bisectionchoice}		{return(token::BISECTIONCHOICE);}
{bisectionparts}		{return(token::BISECTIONPARTS);}
{nobisection}			{return(token::NOBISECTION);}

{bisectionchoicerr}		{return(token::BISECTIONCHOICERR);}
{bisectionchoicelf}		{return(token::BISECTIONCHOICELF);}
{bisectionchoicemn}		{return(token::BISECTIONCHOICEMN);}

{bisectionnumber}		{return(token::BISECTIONNUMBER);}
{bisectionsubpaving}	{return(token::BISECTIONSUBPAVING);}
{bisectionpoints}		{return(token::BISECTIONPOINTS);}

{precision}				{return(token::PRECISION);}

{mode}					{return(token::MODE);}
{outputhullmode}		{return(token::OUTPUTHULLMODE);}
{outputunionmode}		{return(token::OUTPUTUNIONMODE);}
{outputdigits}			{return(token::OUTPUTDIGITS);}

{outputstyle}			{return(token::OUTPUTSTYLE);}
{outputboundstyle}		{return(token::OUTPUTBOUNDSTYLE);}
{outputmidpointstyle}	{return(token::OUTPUTMIDPOINTSTYLE);}

{outputsolution}		{return(token::OUTPUTSOLUTION);}
{outputallsolution}		{return(token::OUTPUTALLSOLUTION);}

{pragmaconsistency}		{return(token::PRAGMACONSISTENCY);}
{localconsistency}		{return(token::LOCALCONSISTENCY);}
{strongconsistency}		{return(token::STRONGCONSISTENCY);}


{consistencybc3}		{return(token::CONSISTENCYBC3);}
{consistencybc3newton}	{return(token::CONSISTENCYBC3Newton);}
{consistencybc4}		{return(token::CONSISTENCYBC4);}
{consistencybc5}		{return(token::CONSISTENCYBC5);}
{consistencyhc3}		{return(token::CONSISTENCYHC3);}
{consistencyhc4}		{return(token::CONSISTENCYHC4);}
{consistencyhc4i}		{return(token::CONSISTENCYHC4I);}
{consistencyhc4newton}	{return(token::CONSISTENCYHC4Newton);}
{precision2b}			{return(token::PRECISION2B);}
{consistency3b}			{return(token::CONSISTENCY3B);}
{consistencyweak3b}		{return(token::CONSISTENCYWEAK3B);}
{precision3b}			{return(token::PRECISION3B);}
{improvement2b}			{return(token::IMPROVEMENT2B);}

{minimum}				{return(token::MINIMUM);}
{maximum}				{return(token::MAXIMUM);}

{integertype}			{return(token::INTEGERTYPE);}
{realtype}				{return(token::REALTYPE);}

{twopoints}				{return(token::TWOPOINTS);}

{realposinfinity}		{return(token::REALPOSINFINITY);}
{realneginfinity}		{return(token::REALNEGINFINITY);}
{pred}					{return(token::PRED);}
{succ}					{return(token::SUCC);}

{dollar}				{return(token::NEWDATA);}

in						{return(token::INDOM);}
sqrt					{return(token::SQRT);}
log						{return(token::LOG);}
exp						{return(token::EXP);}
cos						{return(token::COS);}
sin						{return(token::SIN);}
tan						{return(token::TAN);}
cosh					{return(token::COSH);}
sinh					{return(token::SINH);}
tanh					{return(token::TANH);}
acos					{return(token::ACOS);}
asin					{return(token::ASIN);}
atan					{return(token::ATAN);}
acosh					{return(token::ACOSH);}
asinh					{return(token::ASINH);}
atanh					{return(token::ATANH);}

{ident}					{return(token::IDENT);}
{lsbr}					{return(token::LSBR);}
{rsbr}					{return(token::RSBR);}
{lbr}					{return(token::LBR);}
{rbr}					{return(token::RBR);}
[;]						{return(token::SCOLON);}
[:]						{return(token::COLON);}
[,]						{return(token::COMMA);}
[_]						{return(token::UNDERSCORE);}
[=]						{return(token::EQU);}
{psup}					{return(token::SUP);}
{pinf}					{return(token::INF);}

{add}					{return(token::ADD);}
{sub}					{return(token::SUB);}
[*]						{return(token::MUL);}
{div}					{return(token::DIV);}
{pow}					{return(token::POW);}

{integer1}				{return(token::INTEGER);}
{float1}				{return(token::FLOAT);}
{float2}				{return(token::FLOAT);}
{float3}				{return(token::FLOAT);}


"/*" {
		register int c;
		for( ;; )
		{
		  while( (c=yyinput()) != '*' && c!=EOF )
		  {
			if( c=='\n' ) yylloc->step();
		  }
		  ; // eat up text of comment

		  if( c=='*' )
		  {
			while( (c=yyinput()) == '*' )
			{
			  if( c=='\n' ) yylloc->step();
			}
			;
			if( c=='/' ) break;	   //end of comment
			if( c=='\n' ) yylloc->step();
		  }
		  if( c==EOF ) { break; }  //illegal EOF
		}
	  }

{enter}					{ yylloc->lines(yyleng); yylloc->step(); }
{space}					{ yylloc->step(); }
{comment}				{ }

%% /// additional code

namespace elisa
{

ElisaLexer::ElisaLexer(std::istream *yyin, std::ostream *yyout)
	: yyFlexLexer(yyin, yyout) 
{}

ElisaLexer::~ElisaLexer() {}

}


#ifdef yylex
#undef yylex
#endif

int yyFlexLexer::yylex()
{
	std::cerr << "in yyFlexLexer::yylex() !" << std::endl;
	return 0;
}

int yyFlexLexer::yywrap()
{
	return 1;
}
